<?php

namespace app\controller;

use think\facade\Cache;
use Lcobucci\JWT\Builder;
use Lcobucci\JWT\Signer\Hmac\Sha256;
use Lcobucci\JWT\Parser;
use Lcobucci\JWT\ValidationData;


class Token extends Base
{
    public function initialize()
    {
        parent::initialize();
    }


    //
    // 验证接口数据
    // @param $userid 用户信息是否可用
    // @param $token 用户信息是否可用
    // @param $isuser array 是否验证用户信息
    // @return bool
    //
    public static function apisecurity($isuser = true)
    {
        //合并post|get 防止param有多余信息,如没有任何参数则返回
        $param = @array_merge(_post(), _get());
        //验证用户信息
        if (!request()->header('accessToken')) {
            _Result('应用凭证未发送!!!', 400);
        }
        $accessToken = Token::signTosecret(request()->header('accessToken'));
        if (!$accessToken) {
            _Result('应用凭证未发送!!!', 400);
        }
        if (!db('app', 'mysql')->where('app_id', $accessToken['app_id'])->where('app_secret', $accessToken['app_secret'])->cache('getAppFind_' . $accessToken['app_id'])->find()) {
            _Result('应用凭证未发送!!!', 400);
        }

        if ($isuser) {
            if (empty($param) && !request()->header('token') && !request()->header('secret')) {
                _Result('访问异常!', 400);
            }

            if (!request()->header('secret')) {
                _Result('用户登录状态已失效，请重新登录!!!', 400);
            }
            $secret = Token::validateSecret(request()->header('secret'), true);
            if (!$secret) {
                _Result('用户未登录，请去"我的"登录!!!', 400);
            }
            //验证token是否有效 token及userid
            if (!request()->header('token')) {
                _Result('用户登录状态已失效，请重新登录!', 400);
            }
            $token =  Token::validateToken(request()->header('token'), true);
            if (!$token) {
                _Result('用户未登录，请去先登录!', 400);
            }
            $cache = Cache::get('token' . $token);
            if (!$cache) {
                _Result('登录状态异常', 400);
            }
            if (strpos($cache, request()->header('token')) === false) {
                _Result('登录状态异常', 400);
            }
        }
    }

    //
    //检测Token是否过期与篡改
    //@param token
    //@param return
    //@return boolean/string
    //
    public static function validateToken($tokens = null, $return = false)
    {
        try {
            $token = (new Parser())->parse((string) $tokens);
        } catch (\Throwable $th) {
            _Result('用户登录状态已失效，请重新登录!', 400);
            return false;
        }
        $uid = $token->getClaim('uid');
        // if ($uid != $userid) {
        //     return false; //用户id不正确
        // }
        $signer = new Sha256();
        if (!$token->verify($signer, 'e24463fa21e497d7')) {
            return false; //签名不正确
        }
        $validationData = new ValidationData();
        $validationData->setIssuer('http://www.hljmdd.cn');
        $validationData->setAudience('http://www.hljmdd.cn');
        $validationData->setId('mdd-4f1g23a12aa'); //自字义标识
        if ($return) {
            return $uid;
        } else {
            return $token->validate($validationData);
        }
    }

    //
    //检测secret
    //@param secret
    //@param return
    //@return boolean/array
    //
    public static function validateSecret($secret = '', $return = false)
    {
        $secret = Token::signTosecret($secret);
        if (!$secret) {
            return false;
        }
        if ($return) {
            return $secret;
        }
        return true;
    }



    /**
     *base64转十六进制转字符串转数组函数
     *@pream string $hex='616263';
     */
    public static function signTosecret($str = "")
    {
        $array = str2arr($str, '.');
        unset($array[4]);
        $base = arr2str($array, '');
        $hex = base64_decode($base);
        $str = '';
        for ($i = 0; $i < strlen($hex) - 1; $i += 2) {
            $str .= chr(hexdec($hex[$i] . $hex[$i + 1]));
        }
        return @json_decode($str, true);
    }
}
